<template>
  <div class="publish">
    <!-- 1.面包屑 -->
    <el-breadcrumb separator="/">
      <el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
      <el-breadcrumb-item :to="{ path: '/home/post_publish' }">{{
        this.id ? "文章编辑" : "文章提交"
      }}</el-breadcrumb-item>

      <el-card class="box-card">
        <!-- 主题容器 -->
        <el-form ref="form" :model="form" label-width="80px" :rules="rules">
          <el-form-item label="标题" prop="title">
            <el-input v-model="form.title"></el-input>
          </el-form-item>
          <el-form-item label="栏目" prop="categories">
            <!-- 大选中框 -->
            <el-checkbox
              :indeterminate="isIndeterminate"
              v-model="checkAll"
              @change="handleCheckAllChange"
            >
              全选</el-checkbox
            >

            <!-- 小选中框 -->
            <el-checkbox-group v-model="form.categories">
              <el-checkbox
                v-for="item in cateList"
                :key="item.id"
                :label="item.id"
                name="categories"
              >
                {{ item.name }}
              </el-checkbox>
            </el-checkbox-group>
          </el-form-item>
          <el-form-item label="类型">
            <el-radio-group v-model="form.type">
              <el-radio :label="1">文章</el-radio>
              <el-radio :label="2">视频</el-radio>
            </el-radio-group>
          </el-form-item>
          <!-- 内容 -->
          <template>
            <el-form-item label="内容">
              <!-- 收集文章内容 -->
              <VueEditor
                :config="config"
                ref="vueEditor"
                v-show="form.type === 1"
              ></VueEditor>
              <!-- 收集视频 -->
              <el-upload
                v-show="form.type === 2"
                class="upload-demo"
                :action="this.$baseURL + '/upload'"
                :headers="headers"
                :limit="1"
                :on-success="videoSu"
                :before-upload="videoBeforeUpload"
                :on-remove="videoRemove"
                :file-list="videoList"
              >
                <el-button size="small" type="primary">点击上传</el-button>
                <div slot="tip" class="el-upload__tip">
                  只能上传jpg/png文件，且不超过500kb
                </div>
              </el-upload>
            </el-form-item>
          </template>
          <!-- 封面 -->
          <!--  :on-success="handlePictureCardPreview" 如果不是success就会传不到图片上去 
          文件上传成功时的钩子
           -->
          <el-form-item label="封面">
            <el-upload
              :action="this.$baseURL + '/upload'"
              list-type="picture-card"
              :on-success="handlePictureCardPreview"
              :on-remove="handleRemove"
              :limit="3"
              :on-exceed="onExceed"
              :headers="headers"
              :file-list="formCover"
            >
              <i class="el-icon-plus"></i>
            </el-upload>
          </el-form-item>

          <el-form-item>
            <el-button type="primary" @click="onSubmit">{{
              this.id ? "编辑" : "提交"
            }}</el-button>
            <el-button>取消</el-button>
          </el-form-item>
        </el-form>
      </el-card>
    </el-breadcrumb>
  </div>
</template>

<script>
import VueEditor from "vue-word-editor";
import "quill/dist/quill.snow.css";
import { getCategoryAPI } from "@/apis/category";
import { getToken } from "@/utils/localData";
import {
  getPostDetailByIdAPI,
  publishPostAPI,
  updatePostAPI,
} from "@/apis/news";

export default {
  data() {
    return {
      id: this.$route.params.id,
      //设置上传的请求头部 验证token
      headers: { Authorization: getToken() },
      // 写在data中，一定要添加config的配置
      config: {
        // 上传图片的配置
        uploadImage: {
          url: this.$baseURL + "/upload",
          name: "file",
          headers: { Authorization: getToken() },
          // res是结果，insert方法会把内容注入到编辑器中，res.data.url是资源地址
          uploadSuccess: (res, insert) => {
            console.log(res);

            if (res.data.message === "文件上传成功") {
              //this指向有问题 如果不是箭头函数this指向window 如果是箭头函数指向是vue
              insert(this.$baseURL + res.data.data.url);
            } else {
              this.$message.warning("上传有误");
            }
          },
        },
      },
      //视频展示
      videoList: [],
      formCover: [],
      form: {
        title: "", //标题
        type: 1, //类型的管理
        categories: [], //选中的栏目
        content: "", // 文章内容
        cover: [], // 封面图片ID集合
      },
      //这个是判断标题和其他项目的，名字开头要对应title就是title categories就是categories
      rules: {
        title: [
          { required: true, message: "请输入活动名称", trigger: "blur" },
          { min: 2, max: 5, message: "长度在 3 到 5 个字符", trigger: "blur" },
        ],
        categories: [
          {
            type: "array",
            required: true,
            message: "请至少选择一个栏目",
            trigger: "change",
          },
        ],
      },
      cateList: [],
      checkAll: false,
      //这个权限会比checkall高，我为true 你也要跟着我
      isIndeterminate: false,
    };
  },
  components: {
    VueEditor,
  },
  async created() {
    //获取数据 给到数组里面去
    const res = await getCategoryAPI();
    console.log(res);
    //删除前面几个关注的栏目
    this.cateList = res.data.data.slice(2);
    //如果有id
    if (this.id) {
      //获取接口文档数据
      const res2 = await getPostDetailByIdAPI(this.id);
      console.log(res2);
      //  然后给到res3
      const res3 = res2.data.data;
      //  如果有数据
      if (res3) {
        //就把数据里面的title标题给到现在的标题
        this.form.title = res3.title;
        this.form.type = res3.type;
        this.form.categories = res3.categories.map((item) => item.id);
        this.form.content = res3.content;
        if (this.form.type === 1) {
          //展示文本内容
          const quill = this.$refs.vueEditor.editor;
          quill.clipboard.dangerouslyPasteHTML(0, res3.content);
        } else {
          //展示视频
          this.videoList = [{ name: "mp4", url: res3.content }];
        }
        // this.form.cover=res3.cover.this.$baseURL + "/upload"
        //封面
        // map 返回来的是数组
        this.formCover = res3.cover.map((item) => {
          return { id: item.id, name: item.id, url: this.$baseURL + item.url };
        });
        console.log(this.formCover);
      } else {
        this.$message.warning("文章不存在");
      }
    }
  },
  methods: {
    //视频移除时
    videoRemove() {
      this.form.content = "";
      return false;
    },
    //上传前触发的钩子
    videoBeforeUpload(file) {
      console.log("返回file", file);
      //如果类型不是mp4，或者大于等于1024*1024 就报错
      if (file.type !== "video/mp4" || file.size >= 1024 * 1024) {
        this.$message.warning("请上传mp4格式或者不超过1024*1024的文件");

        return false;
      }
    },
    //视频上传成功后的钩子
    videoSu(res) {
      console.log(res);
      //拿到数据的地址拼接到基地址然后给回去文章内容
      this.form.content = this.$baseURL + res.data.url;
      console.log("我的", this.form.content);
    },

    onExceed() {
      //提示页面不可以超过三张,因为上面已经绑定了
      this.$message.warning("封面不能超出3张哦");
    },
    // 文件上传成功后的钩子函数
    handlePictureCardPreview(res) {
      console.log(1111, "文件上传成功时的钩子", res);
      // 封面数组也要按接口文档要求来 id: res.data.id  数据库的id给回去点击的id 就是图片的id
      this.form.cover.push({ id: res.data.id });
    },
    //文件移除文件时的钩子
    handleRemove(file) {
      console.log(2222, "文件列表移除文件时的钩子", file);
      // 获取到 id
      const id = file.response ? file.response.data.id : file.id;
      // 图片删除了， id 也要被删除
      this.form.cover = this.form.cover.filter((item) => item.id !== id);
    },
    //发布前需要验证 检查数据是否为空
    async onSubmit() {
      // 0.1标题不能为空
      if (this.form.title.trim().length < 3) {
        return this.$message.warning("标题不符合规则");
      }
      // 0.2 栏目至少选中一个栏目
      if (this.form.categories.length === 0) {
        return this.$message.warning("至少选中一个栏目");
      }
      console.log(this.form);
      // 0.3 封面不能为空
      if (this.form.cover.length === 0) {
        return this.$message.warning("至少选中一个图片");
      }
      // 0.4 如果文章类型，type必须等于一
      // console.log(1);
      //如果type值为一 就把图片插入到页面中
      if (this.form.type === 1) {
        //判断type是不是一，把我富文本输入的内容传到数据库那边

        this.form.content = this.$refs.vueEditor.editor.root.innerHTML;
      }
      // 0.5发布内容不能为空
      if (this.form.content === "<p><br></p>") {
        return this.$message.warning("内容不能为空");
      } else if (this.form.type === 2 && this.form.content == "") {
        return this.$message.warning("请上传视频");
      }

      //转换成后端所需的格式
      const data = {
        ...this.form,
        cover: this.form.cover.map((item) => {
          return { id: item.id };
        }),
        //后端要求格式{id:1},{id:2}格式
        categories: this.form.categories.map((item) => {
          return { id: item };
        }),
      };

      //调用发送请求,拿到发布请求的数据 如果没有data  那接口是传不过去文档或者后端的数据的
      //传过来的东西是为空的

      if (this.id) {
        const res = await updatePostAPI(this.id, data);
        if (res.data.message === "文章编辑成功") {
          const tips = this.form.type === 1 ? "文章编辑成功" : "视频编辑成功";
          this.$message.success(tips);
          //成功后跳转和添加一起做 因为$router是路由可以跳转。push可以添加到最后一个
          //所以这里有两个功能
          this.$router.push("/home/post_list");
        }
        console.log(res);
      } else {
        const res = await publishPostAPI(data);

        console.log(res);
        if (res.data.message === "文章发布成功") {
          const tips = this.form.type === 1 ? "文章发布成功" : "视频发布成功";
          this.$message.success(tips);
          //成功后跳转和添加一起做 因为$router是路由可以跳转。push可以添加到最后一个
          //所以这里有两个功能
          this.$router.push("/home/post_list");
        }
      }
    },
    handleCheckAllChange(val) {
      console.log(val);
      // val 获取全选所有状态
      // this.checkedCities = val ? cityOptions : [];
      //如果未teur map处理后返回栏目数组
      // map 拿出来id 另成一个数组只有id的
      this.form.categories =
        val === true ? this.cateList.map((item) => item.id) : [];
      //不确定状态未false
      this.isIndeterminate = false;
    },
  },
  watch: {
    //监听栏目选项
    "form.categories"(value) {
      console.log(value);
      // 选中状态等于选中状态的数组的长度
      let checkedCount = value.length;
      //选框的状态等于 选中状态==数组的长度
      this.checkAll = checkedCount === this.cateList.length;
      //然后不确定状态等于选中状态》0和小于数组的长度
      this.isIndeterminate =
        checkedCount > 0 && checkedCount < this.cateList.length;
    },
  },
};
</script>

<style lang="less" scoped>
.box-card {
  margin-top: 25px;
}
</style>
